#include "Input.h"
#include "Game.h"
#include "Errors.h"

Input::Input() {}

Input::~Input() {
	if(this->mouse != NULL) {
		this->mouse->Unacquire();
		this->mouse->Release();
		this->mouse = NULL;
	}

	if(this->keyboard != NULL) {
		this->keyboard->Unacquire();
		this->keyboard->Release();
		this->keyboard = NULL;
	}

	if(this->directInput != NULL) {
		this->directInput->Release();
		this->directInput = NULL;
	}

	ShowCursor(TRUE);
}

int Input::Initialize(HINSTANCE& hInstance) {

	ShowCursor(FALSE);

	this->inputState = Play;

	SecureZeroMemory(&this->KeysPressed, sizeof(this->KeysPressed));
	SecureZeroMemory(&this->ToggledKeys, sizeof(this->ToggledKeys));

	this->pageCount = 1;

	this->mouseX = windowSize.right / 2.0f;
	this->mouseY = windowSize.bottom / 2.0f;

	if(FAILED(DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, (void**)&this->directInput, NULL))) return E_INPUT_DI_INIT_FAILED;

	if(FAILED(this->directInput->CreateDevice(GUID_SysKeyboard, &this->keyboard, NULL))) return E_INPUT_KEYBOARD_CREATE_FAILED;

	if(FAILED(this->keyboard->SetDataFormat(&c_dfDIKeyboard))) return E_INPUT_KEYBOARD_SETDATAFORMAT_FAILED;

	if(FAILED(this->keyboard->SetCooperativeLevel(Game::window, DISCL_FOREGROUND | DISCL_EXCLUSIVE))) return E_INPUT_KEYBOARD_SETCOOPERATIVELEVEL_FAILED;

	if(FAILED(this->keyboard->Acquire())) return E_INPUT_KEYBOARD_ACQUIRE_FAILED;

	if(FAILED(this->directInput->CreateDevice(GUID_SysMouse, &this->mouse, NULL))) return E_INPUT_MOUSE_CREATE_FAILED;

	if(FAILED(this->mouse->SetDataFormat(&c_dfDIMouse))) return E_INPUT_MOUSE_SETDATAFORMAT_FAILED;

	if(FAILED(this->mouse->SetCooperativeLevel(Game::window, DISCL_FOREGROUND | DISCL_NONEXCLUSIVE))) return E_INPUT_MOUSE_SETCOOPERATIVELEVEL_FAILED;

	if(FAILED(this->mouse->Acquire())) return E_INPUT_MOUSE_ACQUIRE_FAILED;

	return NO_ERRORS;
}

void Input::HandleInput(/*UINT param*/) {

	HRESULT result;

	result = this->keyboard->GetDeviceState(sizeof(this->keyboardState), (LPVOID)&this->keyboardState);
	if(FAILED(result)) if((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED)) this->keyboard->Acquire();

	result = this->mouse->GetDeviceState(sizeof(DIMOUSESTATE), (LPVOID)&this->mouseState);
	if(FAILED(result)) if((result == DIERR_INPUTLOST) || (result == DIERR_NOTACQUIRED)) this->mouse->Acquire();

	switch(this->inputState) {
	case Play:
		{
			if((this->keyboardState[DIK_ESCAPE] & 0x80) && !this->KeysPressed.escape) {
				this->ToggledKeys.escape = !this->ToggledKeys.escape;
			}

			if((this->keyboardState[DIK_PRIOR] & 0x80) && !this->KeysPressed.pageup) this->pageCount++;
			if((this->keyboardState[DIK_NEXT] & 0x80) && !this->KeysPressed.pagedown) {
				this->pageCount--;

				if(this->pageCount < 1) this->pageCount = 1;
			}

			if((this->keyboardState[DIK_F12] & 0x80) && !this->KeysPressed.F12) this->ToggledKeys.F12 = !this->ToggledKeys.F12;
			
			this->KeysPressed.pageup = this->keyboardState[DIK_PRIOR] & 0x80;
			this->KeysPressed.pagedown = this->keyboardState[DIK_NEXT] & 0x80;
			this->KeysPressed.escape = this->keyboardState[DIK_ESCAPE] & 0x80;
			this->KeysPressed.left = this->keyboardState[DIK_LEFTARROW] & 0x80;
			this->KeysPressed.right = this->keyboardState[DIK_RIGHTARROW] & 0x80;
			this->KeysPressed.down = this->keyboardState[DIK_DOWNARROW] & 0x80;
			this->KeysPressed.up = this->keyboardState[DIK_UPARROW] & 0x80;
			this->KeysPressed.del = this->keyboardState[DIK_DELETE] & 0x80;
			this->KeysPressed.num2 = this->keyboardState[DIK_NUMPAD2] & 0x80;
			this->KeysPressed.num4 = this->keyboardState[DIK_NUMPAD4] & 0x80;
			this->KeysPressed.num6 = this->keyboardState[DIK_NUMPAD6] & 0x80;
			this->KeysPressed.num8 = this->keyboardState[DIK_NUMPAD8] & 0x80;
			this->KeysPressed.numplus = this->keyboardState[DIK_ADD] & 0x80;
			this->KeysPressed.numminus = this->keyboardState[DIK_SUBTRACT] & 0x80;
			this->KeysPressed.endkey = this->keyboardState[DIK_END] & 0x80;
			this->KeysPressed.F12 = this->keyboardState[DIK_F12] & 0x80;

		} break;

	case Write:
		{

		} break;
	}

	this->mouseX += this->mouseState.lX;
	this->mouseY += this->mouseState.lY;

	if(this->mouseX < 0) this->mouseX = 0;
	if(this->mouseY < 0) this->mouseY = 0;
	if(this->mouseX > windowSize.right) this->mouseX = windowSize.right;
	if(this->mouseY > windowSize.bottom) this->mouseY = windowSize.bottom;

	Game::CursorPtr->UpdateQuad(this->mouseX, this->mouseY);

	if(GetFocus() == Game::window) SetCursorPos(windowSize.right / 2.0f, windowSize.bottom / 2.0f);
	
}